﻿package com.teaphy.coroutinecrawler.callback

import com.google.gson.Gson
import kotlinx.coroutines.*
import kotlinx.coroutines.internal.resumeCancellableWith
import okhttp3.*
import java.io.IOException
import java.lang.Exception
import kotlin.coroutines.resumeWithException


fun main() = runBlocking {
    val okHttpClient = OkHttpClient()

    val url = "https://gitee.com/teaphy_admin/coroutine_crawler/raw/master/user.json"
    val userRequest = Request.Builder()
        .url(url)
        .build()


    val call: Call = okHttpClient.newCall(userRequest)
//    val userResponse: Response = call.execute()
//    val userResult: String? = userResponse.body?.string()
//    println("userResult: $userResult")
//
//    val gson = Gson()
//    val userBean = gson.fromJson<UserBean>(userResult, UserBean::class.java)
//    println("普通请求 - userBean: $userBean")
//    call.enqueue(object : Callback{
//        override fun onFailure(call: Call, e: IOException) {
//        }
//
//        override fun onResponse(call: Call, response: Response) {
//        }
//
//    })

    val job = launch {
        val userBean = call.await(classOfT = UserBean::class.java)
        println("Coroutine - userBean: $userBean")
    }

    job.join()

    println("runBlockingEnd")
}

data class UserBean(val name: String, val age: Int, val isMale: Boolean)

suspend fun <T> Call.await(classOfT: Class<T>): T {
    return suspendCancellableCoroutine { cont ->
        enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                cont.resumeWithException(e)
            }

            override fun onResponse(call: Call, response: Response) {

                if (!response.isSuccessful) {
                    cont.resumeWithException(Exception("请求错误"))
                    return
                }

                try {
                    val body = response.body

                    if (null == body) {
                        cont.resumeWithException(Exception("返回数据为空"))
                        return
                    }
                    val responseStr = body.string()
                    val gson = Gson()
                    val result: T = gson.fromJson<T>(responseStr, classOfT)
                    cont.resume(result, null)
                } catch (e: Exception) {
                    cont.resumeWithException(e)
                }
            }
        })
    }
}
